class Compiler {
    constructor(vm) {
        this.vm = vm
        this.el = vm.$el
        this.compiler(this.el)
    }
    compiler(el) {
        let childrenNodes = el.childNodes
        Array.from(childrenNodes).forEach(item => {
            if (this.isTextNode(item)) {
                this.compilerText(item)
            } else if (this.isElementNode(item)) {
                this.compilerElement(item)
            }
            if (item.childNodes && item.childNodes.length) {
                this.compiler(item)
            }
        })
    }
    compilerElement(node) {
        Array.from(node.attributes).forEach(item => {
            if (this.isDerictive(item.name)) {
                if (item.name.startsWith('v-on:')) {
                    let hand = item.name.replace('v-on:', '')
                    let updatenode = this[hand + 'update']
                    updatenode && updatenode(node, item, hand, this.vm)
                } else {
                    let updatenode = this[item.name.substr(2) + 'update']
                    updatenode && updatenode(node, item, this.vm.$data[item.value])
                }
            }

        })
    }
    htmlupdate(node, item, value) {
        node.innerHTML = value
    }
    textupdate(node, item, value) {
        node.innerText = value
    }
    modelupdate(node, item, value) {
        node.value = value
    }
    clickupdate(node, item, value, vm) {
        node['on' + value] = vm.$options.methods[item.value]
    }
    compilerText(node) {
        var reg = /\{\{(.+?)\}\}/
        if (reg.test(node.textContent)) {
            var key = RegExp.$1.trim()
            node.textContent = this.vm.$data[key]
        }
    }
    isTextNode(node) {
        return node.nodeType === 3
    }
    isElementNode(node) {
        return node.nodeType === 1
    }
    isDerictive(attrname) {
        return attrname.startsWith('v-')
    }
}